package com.zmn.oms.business.impl.work;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.math.MathUtil;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.consts.GlobalConsts;
import com.zmn.erp.common.newbiz.dio.conf.ConfSubsidyMultipleDIO;
import com.zmn.erp.common.newbiz.dro.conf.ConfSubsidyMultipleDRO;
import com.zmn.erp.dubbo.interfaces.newbiz.conf.ConfEngineerSubsidyRemoteListService;
import com.zmn.erp.dubbo.interfaces.newbiz.conf.ConfSpSubsidyRemoteListService;
import com.zmn.oms.business.interfaces.performance.PerformanceUtilService;
import com.zmn.oms.business.interfaces.work.OrderWorkERPQueryBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.vo.KVDict;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.erp.BasicSharingVO;
import com.zmn.oms.model.vo.work.erp.PerfSharingVO;
import com.zmn.oms.model.vo.work.erp.SharingEstimateVO;
import com.zmn.oms.model.vo.work.erp.SubsidySharingVO;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.performance.common.dro.conf.five.ConfBonusFiveDRO;
import com.zmn.performance.dubbo.interfaces.conf.five.ConfEngineerFiveListRemoteService;
import com.zmn.performance.dubbo.interfaces.conf.five.ConfSpFiveListRemoteService;
import com.zmn.performance.dubbo.interfaces.order.OrderTimeoutWarningListRemoteService;
import com.zmn.base.plat.engine.common.constant.CompanyConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author sunlife
 * @date:2020/10/15 4:27 下午
 * description:
 */
@Service
@Slf4j
public class OrderWorkERPQueryBServiceImpl implements OrderWorkERPQueryBService {
    @Resource
    OrderWorkService orderWorkService;
    @Resource
    OrderServiceItemService orderServiceItemService;
    @Resource
    PerformanceUtilService performanceUtilService;


    @Reference(version = com.zmn.erp.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    ConfEngineerSubsidyRemoteListService confEngineerSubsidyRemoteListService;
    @Reference(version = com.zmn.erp.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    ConfSpSubsidyRemoteListService confSpSubsidyRemoteListService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    OrderTimeoutWarningListRemoteService orderTimeoutWarningListRemoteService;
    @Reference(version = com.zmn.performance.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    ConfSpFiveListRemoteService confSpFiveListRemoteService;
    @Reference(version = com.zmn.performance.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    ConfEngineerFiveListRemoteService confEngineerFiveListRemoteService;

    @Override
    public Integer haveSharingEstimate(OrderWork orderWork) {
        if (Objects.isNull(orderWork)) {
            return GlobalConsts.NO;
        }
        // F端 新单 言而有信平台 已分单-已收单 无取消时间
        if (!(Objects.equals(orderWork.getBizType(), GlobalConsts.BIZ_TYPE_F) && Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_NEW)
                && Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_YEYX)
                && (orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_ASSIGN)
                && orderWork.getStatus() < OrderStatusConsts.WORK_STATUS_ACCOUNT
                && Objects.isNull(orderWork.getCancelTime()))) {
            return GlobalConsts.NO;
        }
        return GlobalConsts.YES;
    }

    @Override
    public SharingEstimateVO findSharingEstimate(Long orderId, Long workId, Boolean needProcessSublist, Boolean filterEngineer) throws OmsBaseException {

        SharingEstimateVO sharingEstimate = new SharingEstimateVO();

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);

        if (Objects.equals(GlobalConsts.NO, this.haveSharingEstimate(orderWork))) {
            throw new OmsBaseException(String.format("工单：[%s]不可展示分润预估", workId));
        }
        if (filterEngineer && !Objects.equals(orderWork.getManageCompanyType(), CompanyConsts.COMPANY_TYPE_SERVICE_OCO)) {
            throw new OmsBaseException("app分润预估只在直营服务商下工程师app展示");
        }

        sharingEstimate.setTypeName(Objects.equals(orderWork.getManageCompanyType(), CompanyConsts.COMPANY_TYPE_SERVICE_OCO) ? "工程师" : "服务商");


        // 绩效部分金额
        ResponseDTO<ConfBonusFiveDRO> confBonusFiveDRORsp = null;

        // 补贴部分金额
        ConfSubsidyMultipleDIO confSubsidyMultipleDIO = new ConfSubsidyMultipleDIO();
        confSubsidyMultipleDIO.setPlat(orderWork.getPlatWork());
        confSubsidyMultipleDIO.setAreaId(orderWork.getCityId());
        confSubsidyMultipleDIO.setBizType(orderWork.getBizType());
        confSubsidyMultipleDIO.setChannelId(orderWork.getChannelId());
        confSubsidyMultipleDIO.setCompanyId(orderWork.getManageCompanyId());
        ConfSubsidyMultipleDRO confSubsidyMultipleDRO;

        try {
            if (!Objects.equals(orderWork.getManageCompanyType(), CompanyConsts.COMPANY_TYPE_SERVICE_NOT_OCO)) {
                // 直营 展示工程师相关信息
                // 绩效部分金额
                log.info("#获取工程师激励金配置信息 入参:{},{},{}", orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType());
                confBonusFiveDRORsp = confEngineerFiveListRemoteService.getBonusOnlyById(orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType());

                // 补贴部分金额
                log.info("#获取工程师绩效金配置信息 入参:{}", JSON.toJSONString(confSubsidyMultipleDIO));
                confSubsidyMultipleDRO = confEngineerSubsidyRemoteListService.getSubsidyMultipleByQuery(confSubsidyMultipleDIO);
            } else {
                // 非直营 展示服务商相关信息
                // 绩效部分金额
                log.info("#获取服务商激励金配置信息 入参:{},{},{}", orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType());
//                confBonusFiveDRORsp = confSpFiveListRemoteService.getBonusOnlyById(orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType());
                confBonusFiveDRORsp = null;
                // 补贴部分金额
                log.info("#获取服务商绩效金配置信息 入参:{}", JSON.toJSONString(confSubsidyMultipleDIO));
//                confSubsidyMultipleDRO = confSpSubsidyRemoteListService.getSubsidyMultipleByQuery(confSubsidyMultipleDIO);
                confSubsidyMultipleDRO = null;
            }

            log.info("#获取激励金配置信息 出参:{}", JSON.toJSONString(confBonusFiveDRORsp));
            log.info("#获取绩效金配置信息 出参:{}", JSON.toJSONString(confSubsidyMultipleDRO));

            PerfSharingVO perfSharing = getPerfSharing(orderId,confBonusFiveDRORsp);
            SubsidySharingVO subsidySharing = Optional.ofNullable(BeanMapper.map(confSubsidyMultipleDRO, SubsidySharingVO.class)).orElse(new SubsidySharingVO());
            // 处理区域补贴
            List<OrderServiceItem> items = orderServiceItemService.listByOrderId(orderId);
            if (CollectionUtil.isNotNullOrEmpty(items)) {
                Integer totalAmount = items.stream().mapToInt(OrderServiceItem::getInternalTotalPrice).sum();

                subsidySharing.setAreaSubsidyAmount(MathUtil.mul(Optional.ofNullable(subsidySharing.getAreaSubsidy()).orElse(new BigDecimal(0)).divide(new BigDecimal(100), 4).floatValue(), totalAmount));
            }

            sharingEstimate.setPerfSharing(perfSharing);
            sharingEstimate.setSubsidySharing(subsidySharing);

            // 服务项内外结算价
            int internalSettlementPrice = 0;
            if (CollectionUtil.isNotNullOrEmpty(items)) {
                internalSettlementPrice = items.stream()
                        .filter(e -> NumberUtil.isNotNullOrZero(e.getInternalTotalPrice()))
                        .mapToInt(OrderServiceItem::getInternalTotalPrice).sum();
            }
            if (NumberUtil.isNullOrZero(internalSettlementPrice)) {
                internalSettlementPrice = Optional.ofNullable(orderWork.getOriginalAmount()).orElse(0);
            }
            sharingEstimate.setBasicSharing(new BasicSharingVO(internalSettlementPrice));

            if (needProcessSublist) {
                this.processSubList(sharingEstimate);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("查询绩效错误，工单[{}]，异常信息：{}", orderWork.getWorkId(), ex);
        }

        return sharingEstimate;
    }

    private PerfSharingVO getPerfSharing(Long orderId,ResponseDTO<ConfBonusFiveDRO> confBonusFiveDRORsp) {
        PerfSharingVO perfSharingVO = new PerfSharingVO();
        if (Objects.isNull(confBonusFiveDRORsp) || !confBonusFiveDRORsp.isSuccess()) {
            return perfSharingVO;
        }

        ConfBonusFiveDRO data = confBonusFiveDRORsp.getData();
        perfSharingVO.setCompleteInDay(performanceUtilService.conversionPerformanceAmount(orderId, data.getCompleteInDay(), data.getCompleteInDayValType()));
        perfSharingVO.setOnTimeDuty(performanceUtilService.conversionPerformanceAmount(orderId, data.getOnTimeDuty(), data.getOnTimeDutyValType()));
        perfSharingVO.setOnTimeVisit(performanceUtilService.conversionPerformanceAmount(orderId, data.getOnTimeVisit(), data.getOnTimeVisitValType()));
        perfSharingVO.setPraise(performanceUtilService.conversionPerformanceAmount(orderId, data.getPraise(), data.getPraiseValType()));

        return perfSharingVO;
    }

    private void processSubList(SharingEstimateVO sharingEstimate) {
        PerfSharingVO perfSharing = sharingEstimate.getPerfSharing();
        SubsidySharingVO subsidySharing = sharingEstimate.getSubsidySharing();

        List<KVDict<String>> results = Lists.newArrayList();

        // 绩效部分金额
        if (Objects.nonNull(perfSharing) && NumberUtil.isNotNullOrZero(perfSharing.getTotalAmount())) {
            List<KVDict<String>> perfList = Lists.newArrayList();
            if (NumberUtil.isNotNullOrZero(perfSharing.getOnTimeDuty())) {
                perfList.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(perfSharing.getOnTimeDuty())).text( "及时预约").build());
            }
            if (NumberUtil.isNotNullOrZero(perfSharing.getOnTimeVisit())) {
                perfList.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(perfSharing.getOnTimeVisit())).text( "准时上门").build());
            }
            if (NumberUtil.isNotNullOrZero(perfSharing.getCompleteInDay())) {
                perfList.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(perfSharing.getCompleteInDay())).text( "二十四小时完成").build());
            }
            if (NumberUtil.isNotNullOrZero(perfSharing.getPraise())) {
                perfList.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(perfSharing.getPraise())).text( "好评").build());
            }
            results.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(perfSharing.getTotalAmount())).text( "订单绩效").ext1(JSON.toJSONString(perfList)).build());
        }

        // 补贴部分金额
        if (Objects.nonNull(subsidySharing) && NumberUtil.isNotNullOrZero(subsidySharing.getTotalAmount())) {
            List<KVDict<String>> subsidyList = Lists.newArrayList();
            if (NumberUtil.isNotNullOrZero(subsidySharing.getDistanceSubsidy())) {
                subsidyList.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(subsidySharing.getDistanceSubsidy())).text( "远程补贴").build());
            }
            if (NumberUtil.isNotNullOrZero(subsidySharing.getUrgentSubsidy())) {
                subsidyList.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(subsidySharing.getUrgentSubsidy())).text( "加急补贴").build());
            }
            if (NumberUtil.isNotNullOrZero(subsidySharing.getAreaSubsidy())) {
                if (NumberUtil.isNullOrZero(subsidySharing.getAreaSubsidyAmount())) {
                    subsidyList.add(KVDict.<String>builder().value("+" + subsidySharing.getAreaSubsidy().toString() + "%").text( "区域补贴").build());
                } else {
                    subsidyList.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(subsidySharing.getAreaSubsidyAmount())).text( "区域补贴").build());
                }
            }
            results.add(KVDict.<String>builder().value("+￥" + MoneyUtil.parseToYuanStr(subsidySharing.getTotalAmount())).text( "订单补贴").ext1(JSON.toJSONString(subsidyList)).build());
        }

        sharingEstimate.setSubListJsonStr(JSON.toJSONString(results));
    }

}
